package util.locks;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.LockSupport;

/**
 * @author Khai Loon
 * @date 2018/6/12
 */
public class AQSimp {

    private static class Sync extends AbstractQueuedSynchronizer {

        //是否处于占用状态  state =1 为独占锁
        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        //当状态为0的时候获取锁，CAS操作成功，则state状态为1
        @Override
        protected boolean tryAcquire(int arg) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            if (getState() != arg) {
                throw new IllegalArgumentException("没有锁,释放锁");
            }
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
    }

    private final Sync sync = new Sync();

    public void lock() {
        sync.acquire(1);
    }

    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    public void unlock() {
        sync.release(1);
    }

    public boolean isLocked() {
        return sync.isHeldExclusively();
    }


    public static void main(String[] args) throws InterruptedException {
        AQSimp aqSimp = new AQSimp();

        Thread thread = new Thread(() -> {
            boolean ok = true;
            for (; ; ) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
                System.out.println(111);
                if (ok) {
                    LockSupport.park();
                    ok = false;
                }

            }
        });

        thread.start();


        new Thread(() -> {

            try {
                Thread.sleep(2000);
                System.out.println("结束");
                LockSupport.unpark(thread);
            } catch (InterruptedException e) {

            }
        }).start();


    }

}
